﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace Serviio.API
{
    public class ServiioStatus
    {
        private const string endpoint = "/rest/status";
        private ServiioConnection conn = null;

        internal ServiioStatus(ServiioConnection connection)
        {
            this.conn = connection;
            Refresh();
        }

        public enum ServerStates
        {
            Initializing = 0,
            Started = 1,
            Stopped = 2,
            Unknown
        }

        private string[] statusStrings =
        {
            "INITIALIZING",
            "STARTED",
            "STOPPED"
        };

        private string serverStatusString = null;
        public ServerStates ServerStatus
        {
            get
            {
                for (int i = 0; i < statusStrings.Length; i++)
                {
                    if (statusStrings[i].Equals(serverStatusString))
                        return (ServerStates) i;
                }
                return ServerStates.Unknown;
            }
        }

        public string ServerStatusString
        {
            get
            {
                return serverStatusString != null ?
                    serverStatusString.ToUpperInvariant() :
                    "Unknown";
            }
        }

        public string BoundIpAddress { get; private set; }

        private List<ServiioDevice> devices = new List<ServiioDevice>();
        public List<ServiioDevice> Devices
        {
            get
            {
                return devices;
            }
        }

        public bool Refresh()
        {
            try
            {
                XmlDocument xDoc = RESTHelper.Get(conn.Host + endpoint);

                serverStatusString = xDoc.SelectSingleNode("/status/serverStatus").InnerText;
                XmlNode boundIpAddressNode = xDoc.SelectSingleNode("/status/boundIPAddress");
                BoundIpAddress = boundIpAddressNode != null ? boundIpAddressNode.InnerText : null;

                Devices.Clear();

                XmlNodeList deviceList = xDoc.SelectNodes("/status/renderers/renderer");
                foreach (XmlNode deviceNode in deviceList)
                {
                    if (deviceNode.SelectSingleNode("name") != null)
                    {
                        string deviceId = deviceNode.SelectSingleNode("uuid").InnerText;
                        string deviceName = deviceNode.SelectSingleNode("name").InnerText;
                        string deviceIpAddress = deviceNode.SelectSingleNode("ipAddress").InnerText;
                        string deviceProfileId = deviceNode.SelectSingleNode("profileId").InnerText;
                        string deviceStatus = deviceNode.SelectSingleNode("status").InnerText;

                        Devices.Add(new ServiioDevice(conn, deviceId, deviceIpAddress, deviceName, deviceProfileId, deviceStatus));
                    }
                }
            }
            catch
            {
                return false;
            }

            return true;
        }

        public bool Update()
        {
            try
            {
                XmlDocument xDoc = new XmlDocument();
                XmlDeclaration dec = xDoc.CreateXmlDeclaration("1.0", null, null);
                xDoc.AppendChild(dec);
                XmlElement root = xDoc.CreateElement("status");
                xDoc.AppendChild(root);

                XmlElement renderers = xDoc.CreateElement("renderers");
                root.AppendChild(renderers);

                foreach (ServiioDevice device in Devices)
                {
                    XmlElement renderer = xDoc.CreateElement("renderer");
                    renderers.AppendChild(renderer);

                    XmlElement uuid = xDoc.CreateElement("uuid");
                    uuid.InnerText = device.Uuid;
                    renderer.AppendChild(uuid);

                    XmlElement ipAddress = xDoc.CreateElement("ipAddress");
                    ipAddress.InnerText = device.IpAddress;
                    renderer.AppendChild(ipAddress);

                    XmlElement name = xDoc.CreateElement("name");
                    name.InnerText = device.Name;
                    renderer.AppendChild(name);

                    XmlElement profileId = xDoc.CreateElement("profileId");
                    profileId.InnerText = device.ProfileId;
                    renderer.AppendChild(profileId);
                }

                if (BoundIpAddress != null)
                {
                    XmlElement boundIpAddress = xDoc.CreateElement("boundIPAddress");
                    boundIpAddress.InnerText = BoundIpAddress;
                    root.AppendChild(boundIpAddress);
                }

                return RESTHelper.Put(conn.Host + endpoint, xDoc);
            }
            catch
            {
                return false;
            }
        }
    }
}
